import React from 'react'
import ReactDOM from 'react-dom'

function withSticky(WrappedComponent) {
  
  class Sticky extends React.Component {
    constructor(props) {
      super(props)
      this.state = {
        isFixed: false,
        width: 0,
        height: 0
      };
      this.wrapDomRef = React.createRef();
    }
    listenScroll = () => {
      const rect = this.wrapDomRef.current.getBoundingClientRect();
      if (!this.state.isFixed) {
        if (rect.y < this.props.top) {
          this.setState({
            isFixed: true,
            width: this.wrapDomRef.current.offsetWidth,
            height: this.wrapDomRef.current.offsetHeight,
          });
        }
      } else {
        if (rect.y >= this.props.top) {
          this.setState({
            isFixed: false,
            width: 0,
            height: 0,
          });
        }
      }
      
    }
    listenResize = () => {
      if (this.state.isFixed) {
        const domWrap = this.wrapDomRef.current;
        this.setState({
          width: domWrap.offsetWidth,
          height: domWrap.offsetHeight
        });
      }
    }
    componentDidMount() {
      window.addEventListener('scroll', this.listenScroll)
      window.addEventListener('resize', this.listenResize)
    }
    componentWillUnmount() {
      window.removeEventListener('scroll', this.listenScroll)
      window.removeEventListener('resize', this.listenResize)
    }
    render() {
      const styleObj = this.state.isFixed ? {
        position: 'fixed',
        top: this.props.top,
      } : null;
      return <div ref={this.wrapDomRef}>
        {this.state.isFixed ? <div style={{width: this.state.width, height: this.state.height}}></div> : null}
        <div style={styleObj}>
          <WrappedComponent {...this.props} />
        </div>
      </div>
    }
  }

  Sticky.displayName = 'WithSticky' + (WrappedComponent.displayName || WrappedComponent.name || 'Component');

  return Sticky;

}

function Button1(props) {
  return <button>距离顶部{props.top}px</button>;
}

function Button2(props) {
  return <button style={{backgroundColor: 'lightskyblue'}}>距离顶部{props.top}px</button>;
}

const StickyButton1 = withSticky(Button1);
const StickyButton2 = withSticky(Button2);


class App extends React.Component {
  render() {
    return (
      <div>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Incidunt nesciunt nemo, dignissimos repellendus ut voluptas voluptatum nihil, et officiis ipsam, sapiente ad fugiat quisquam provident sequi alias laudantium neque similique!</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut dolore praesentium fugiat, ducimus quia unde? Quo asperiores minima delectus voluptatibus dolorem! Inventore sapiente dignissimos similique aliquam pariatur nulla consectetur assumenda?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum voluptatum libero quas praesentium veniam exercitationem porro, sit provident fugit harum impedit natus accusantium doloremque molestiae neque mollitia alias. Dolor, adipisci.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus eum magni repellat ratione temporibus ab blanditiis commodi maxime, laboriosam, quisquam tenetur nisi aspernatur qui recusandae velit voluptates deserunt aperiam voluptatem?</p>
        <StickyButton1 top={100} />
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ex veritatis voluptas quis, inventore sit officiis quasi atque, voluptates iure tempora, repellendus sequi. Iusto amet deleniti natus harum molestias libero debitis?</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Qui unde ut officia eius itaque iusto molestias alias odit aliquam corrupti, numquam ab fuga quam quos, consequatur quo, provident nulla distinctio.</p>
        <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Blanditiis, sapiente! Rerum dolorum perspiciatis beatae error qui nobis aperiam recusandae corrupti consequuntur odio quia saepe id ab, ipsa architecto eum deleniti.</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ducimus, nisi inventore consequatur assumenda id maiores quae cum minus ad suscipit omnis nesciunt atque ab corporis totam aspernatur et ipsa repellat.</p>
        <StickyButton2 top={200} />
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab, delectus sequi aperiam voluptatum harum pariatur. Saepe aperiam cumque, quo illo nisi unde accusantium possimus minus praesentium facilis dolorem exercitationem quae?</p>
        <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quaerat natus hic numquam, eum deserunt, aut veniam eveniet officia architecto accusantium suscipit! Officiis delectus commodi, pariatur beatae nam repellendus aperiam necessitatibus.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, illo. Voluptate dolores non quaerat exercitationem explicabo esse perspiciatis ea ullam cum laborum? Tenetur, ea recusandae saepe explicabo magni illum sit!</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Labore quis possimus iste iure veritatis hic architecto reprehenderit qui. Illum similique praesentium deleniti laborum rem repellendus asperiores cumque commodi vitae mollitia.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis quisquam eligendi laudantium exercitationem quam saepe tempora a. Quasi, alias. Sint officiis eos atque quo vero alias reiciendis corrupti praesentium voluptatibus?</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Incidunt nesciunt nemo, dignissimos repellendus ut voluptas voluptatum nihil, et officiis ipsam, sapiente ad fugiat quisquam provident sequi alias laudantium neque similique!</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut dolore praesentium fugiat, ducimus quia unde? Quo asperiores minima delectus voluptatibus dolorem! Inventore sapiente dignissimos similique aliquam pariatur nulla consectetur assumenda?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum voluptatum libero quas praesentium veniam exercitationem porro, sit provident fugit harum impedit natus accusantium doloremque molestiae neque mollitia alias. Dolor, adipisci.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus eum magni repellat ratione temporibus ab blanditiis commodi maxime, laboriosam, quisquam tenetur nisi aspernatur qui recusandae velit voluptates deserunt aperiam voluptatem?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ex veritatis voluptas quis, inventore sit officiis quasi atque, voluptates iure tempora, repellendus sequi. Iusto amet deleniti natus harum molestias libero debitis?</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Qui unde ut officia eius itaque iusto molestias alias odit aliquam corrupti, numquam ab fuga quam quos, consequatur quo, provident nulla distinctio.</p>
        <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Blanditiis, sapiente! Rerum dolorum perspiciatis beatae error qui nobis aperiam recusandae corrupti consequuntur odio quia saepe id ab, ipsa architecto eum deleniti.</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ducimus, nisi inventore consequatur assumenda id maiores quae cum minus ad suscipit omnis nesciunt atque ab corporis totam aspernatur et ipsa repellat.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab, delectus sequi aperiam voluptatum harum pariatur. Saepe aperiam cumque, quo illo nisi unde accusantium possimus minus praesentium facilis dolorem exercitationem quae?</p>
        <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quaerat natus hic numquam, eum deserunt, aut veniam eveniet officia architecto accusantium suscipit! Officiis delectus commodi, pariatur beatae nam repellendus aperiam necessitatibus.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, illo. Voluptate dolores non quaerat exercitationem explicabo esse perspiciatis ea ullam cum laborum? Tenetur, ea recusandae saepe explicabo magni illum sit!</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Labore quis possimus iste iure veritatis hic architecto reprehenderit qui. Illum similique praesentium deleniti laborum rem repellendus asperiores cumque commodi vitae mollitia.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis quisquam eligendi laudantium exercitationem quam saepe tempora a. Quasi, alias. Sint officiis eos atque quo vero alias reiciendis corrupti praesentium voluptatibus?</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Incidunt nesciunt nemo, dignissimos repellendus ut voluptas voluptatum nihil, et officiis ipsam, sapiente ad fugiat quisquam provident sequi alias laudantium neque similique!</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut dolore praesentium fugiat, ducimus quia unde? Quo asperiores minima delectus voluptatibus dolorem! Inventore sapiente dignissimos similique aliquam pariatur nulla consectetur assumenda?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum voluptatum libero quas praesentium veniam exercitationem porro, sit provident fugit harum impedit natus accusantium doloremque molestiae neque mollitia alias. Dolor, adipisci.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus eum magni repellat ratione temporibus ab blanditiis commodi maxime, laboriosam, quisquam tenetur nisi aspernatur qui recusandae velit voluptates deserunt aperiam voluptatem?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ex veritatis voluptas quis, inventore sit officiis quasi atque, voluptates iure tempora, repellendus sequi. Iusto amet deleniti natus harum molestias libero debitis?</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Qui unde ut officia eius itaque iusto molestias alias odit aliquam corrupti, numquam ab fuga quam quos, consequatur quo, provident nulla distinctio.</p>
        <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Blanditiis, sapiente! Rerum dolorum perspiciatis beatae error qui nobis aperiam recusandae corrupti consequuntur odio quia saepe id ab, ipsa architecto eum deleniti.</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ducimus, nisi inventore consequatur assumenda id maiores quae cum minus ad suscipit omnis nesciunt atque ab corporis totam aspernatur et ipsa repellat.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab, delectus sequi aperiam voluptatum harum pariatur. Saepe aperiam cumque, quo illo nisi unde accusantium possimus minus praesentium facilis dolorem exercitationem quae?</p>
        <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quaerat natus hic numquam, eum deserunt, aut veniam eveniet officia architecto accusantium suscipit! Officiis delectus commodi, pariatur beatae nam repellendus aperiam necessitatibus.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, illo. Voluptate dolores non quaerat exercitationem explicabo esse perspiciatis ea ullam cum laborum? Tenetur, ea recusandae saepe explicabo magni illum sit!</p>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Labore quis possimus iste iure veritatis hic architecto reprehenderit qui. Illum similique praesentium deleniti laborum rem repellendus asperiores cumque commodi vitae mollitia.</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis quisquam eligendi laudantium exercitationem quam saepe tempora a. Quasi, alias. Sint officiis eos atque quo vero alias reiciendis corrupti praesentium voluptatibus?</p>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
